Skip to content

chore: navigation rework#152

Merged
hmbanan666 merged 2 commits into
mainfrom
chore
Sep 12, 2025
Merged

chore: navigation rework#152
hmbanan666 merged 2 commits into
mainfrom
chore

Conversation

@hmbanan666

@hmbanan666 hmbanan666 commented Sep 12, 2025

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • New Features

    • Back/return action enabled on Flow and Epic detail pages; navigation now matches by page name as well as path.
    • Navigation shows a task count badge for today’s tasks.
  • Improvements

    • Tasks page now sources and displays today’s tasks and lists from centralized task data.
    • Daily report titles now start with “Задачи {date}”.
  • Style

    • Slide-down animations with staggered delays added to several sections.
    • Larger headings/card text and increased list spacing for improved readability.
    • Active button text and undo icon behavior refined to reflect both path and page name.

@hmbanan666 hmbanan666 self-assigned this Sep 12, 2025
@coderabbitai

coderabbitai Bot commented Sep 12, 2025

Copy link
Copy Markdown

Walkthrough

Route navigation now matches by route path or by an array of route names; page meta names and canReturn flags were added. Several flow components received motion/typography tweaks. Task store gained user- and today-based computed lists; the daily report title was prefixed with "Задачи ". Public NavigationRoute type changed name → names: string[].

Changes

Cohort / File(s) Summary
Navigation components & types
apps/atrium-telegram/app/components/NavigationButton.vue, apps/atrium-telegram/app/composables/useNavigation.ts, apps/atrium-telegram/shared/types/index.ts
Active detection broadened to match by path or by inclusion in a names array; NavigationRoute now uses names: string[] and optional badge; removed isFlowInnerPage/canReturnToMain from composable; undo icon and text styling now depend on name-based matching and meta.canReturn.
Page meta additions & minor layout
apps/atrium-telegram/app/pages/index.vue, apps/atrium-telegram/app/pages/flow/[itemId]/index.vue, apps/atrium-telegram/app/pages/epic/[epicId]/index.vue
Added definePageMeta calls (page name values and canReturn for detail pages); small spacing/heading size adjustments on index and flow item page.
Flow UI motion & typography
apps/atrium-telegram/app/components/flow/FeedbackAverage.vue, .../flow/KitchensOnline.vue, .../flow/OrderAmountAverage.vue, .../flow/OrdersOnline.vue, .../flow/ItemCard.vue
Added motion-preset-slide-down with staggered motion-delay-* classes to Section wrappers; ItemCard increased heading/body font sizes and adjusted line-clamp — purely presentational.
Task store and task UI usage
apps/atrium-telegram/app/stores/task.ts, apps/atrium-telegram/app/pages/tasks/index.vue
task store now exposes myLists (user-filtered lists) and myTodayTasks (uncompleted tasks dated today); page /tasks switched to use store-provided computed values and removed local date-filtering logic.
Server report title
apps/web-app/server/tasks/ai/daily-report.ts
Changed generated flow item title to Задачи ${date} (prefixing the date with "Задачи ").

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant Router
  participant NavigationButton
  participant useNavigation as Navigation composable

  Note over Router,NavigationButton: Pages register meta via definePageMeta(name, canReturn?)
  User->>Router: navigate to path (sets currentRoute { path, name, meta })
  Router-->>NavigationButton: currentRoute

  rect rgb(220,235,255)
    NavigationButton->>NavigationButton: isThisRoute = match path (and exact?)
    NavigationButton->>useNavigation: read mainRoutes (each has `names: []`)
    NavigationButton->>NavigationButton: isThisName = currentRoute.name ∈ route.names
  end

  alt active (isThisRoute or isThisName)
    NavigationButton-->>User: render active styling (tg-text, active classes)
  else inactive
    NavigationButton-->>User: render default styling
  end

  opt return available
    Note right of NavigationButton: meta.canReturn && isThisName
    NavigationButton-->>User: show undo icon (return action)
  end

  opt scroll-to-top
    NavigationButton-->>User: show up-arrow when canScrollToTop
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Pre-merge checks (2 passed, 1 warning)

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "chore: navigation rework" accurately and concisely summarizes the primary change — a navigation refactor touching useNavigation, shared types (name → names), page metadata, and related components — and is directly related to the changes in the diff. It is short, specific to the main concern, and suitable for a teammate scanning commit history.

Poem

A rabbit taps the routes by name,
Hops back when meta says “you may.”
Slides the cards with gentle sway,
Fonts grow tall along the way.
“Задачи” crowns the date today — carrot-check, hooray! 🥕✨

✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chore

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/atrium-telegram/shared/types/index.ts (1)

15-21: Inconsistent NavigationRoute API — storefront-telegram still exposes name: string (breaking).

  • apps/atrium-telegram/shared/types/index.ts → names: string[] and its route defs use names.
  • apps/storefront-telegram/shared/types/index.ts still defines name: string — change to names: string[] and migrate storefront consumers (e.g. apps/storefront-telegram/app/composables/useNavigation.ts, apps/storefront-telegram/app/components/NavigationButton.vue) to read/write route.names.
  • This is a breaking public type change; align types across packages or revert until both are migrated.
🧹 Nitpick comments (9)
apps/atrium-telegram/app/components/flow/OrdersOnline.vue (1)

2-2: Respect reduced-motion preferences for new animations

If your motion preset doesn’t automatically honor prefers-reduced-motion, consider gating with a motion-safe variant or disabling on reduce to avoid accessibility regressions.

apps/atrium-telegram/app/pages/index.vue (1)

14-21: Prefer named-route navigation for resilience

Linking by name survives path changes and keeps params typed.

Apply:

-        :to="`/flow/${item.id}`"
+        :to="{ name: 'flow-itemId', params: { itemId: item.id } }"
apps/atrium-telegram/app/pages/epic/[epicId]/index.vue (1)

26-30: Condition always true; hide comments when list is empty

length >= 0 is always true. Use > 0 to avoid showing a “0 comments” pill.

Apply:

-      <div v-if="epic?.comments && epic?.comments.length >= 0" class="flex flex-row items-center gap-2">
+      <div v-if="epic?.comments && epic?.comments.length > 0" class="flex flex-row items-center gap-2">
apps/atrium-telegram/app/components/flow/ItemCard.vue (1)

9-11: Guard comments length access

If comments can be undefined, this will throw. Safer to chain and default to 0.

Apply:

-    <div class="w-full text-base/5 font-normal whitespace-pre-wrap break-words line-clamp-12">
+    <div class="w-full text-base/5 font-normal whitespace-pre-wrap break-words line-clamp-12">
       {{ item.description }}
     </div>
@@
-          <p>{{ item?.comments.length }}</p>
+          <p>{{ item?.comments?.length ?? 0 }}</p>

Also applies to: 16-18

apps/atrium-telegram/app/components/flow/OrderAmountAverage.vue (1)

2-2: Add reduced-motion consideration to new animation

Ensure the preset respects prefers-reduced-motion or gate it to avoid motion for users who opt out.

apps/atrium-telegram/app/components/flow/FeedbackAverage.vue (1)

2-2: Respect reduced-motion for animation preset

Same advice: gate or auto-respect prefers-reduced-motion to prevent unnecessary motion.

apps/atrium-telegram/app/components/flow/KitchensOnline.vue (1)

2-2: Apply motion with reduced-motion safety on both branches

Good consistency adding presets to both states; add motion-safe handling if the preset doesn’t already.

Also applies to: 23-23

apps/web-app/server/tasks/ai/daily-report.ts (1)

60-61: Avoid hardcoding the Russian title; prefer config/i18n.

Hardcoding "Задачи" limits flexibility. Consider pulling a title prefix from runtime config or an i18n key so environments can localize without code changes.

apps/atrium-telegram/shared/types/index.ts (1)

17-17: Make route names immutable to prevent accidental mutation.

Declare names as readonly for safer typing.

-  names: string[]
+  names: readonly string[]
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 52d9090 and d5eb806.

📒 Files selected for processing (12)
  • apps/atrium-telegram/app/components/NavigationButton.vue (4 hunks)
  • apps/atrium-telegram/app/components/flow/FeedbackAverage.vue (1 hunks)
  • apps/atrium-telegram/app/components/flow/ItemCard.vue (1 hunks)
  • apps/atrium-telegram/app/components/flow/KitchensOnline.vue (2 hunks)
  • apps/atrium-telegram/app/components/flow/OrderAmountAverage.vue (1 hunks)
  • apps/atrium-telegram/app/components/flow/OrdersOnline.vue (1 hunks)
  • apps/atrium-telegram/app/composables/useNavigation.ts (1 hunks)
  • apps/atrium-telegram/app/pages/epic/[epicId]/index.vue (1 hunks)
  • apps/atrium-telegram/app/pages/flow/[itemId]/index.vue (2 hunks)
  • apps/atrium-telegram/app/pages/index.vue (2 hunks)
  • apps/atrium-telegram/shared/types/index.ts (1 hunks)
  • apps/web-app/server/tasks/ai/daily-report.ts (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (11)
apps/atrium-telegram/app/pages/index.vue (2)

13-13: UI spacing change looks good

The increased gap improves scan-ability.


27-29: Avoid duplicating router name in meta; prefer route.name

Ran: rg -n 'currentRoute.value.meta.name|route.meta.name|isFlowInnerPage|canReturnToMain' — no matches found in the repo. Absence of matches isn't definitive; confirm there are no template/runtime or external accesses to meta.name. If none exist, remove meta.name and read router.currentRoute.value.name for active checks; keep meta only for canReturn.

apps/atrium-telegram/app/pages/epic/[epicId]/index.vue (1)

62-65: Page meta aligns with navigation scheme

Meta name and canReturn fit the new names-based navigation.

apps/atrium-telegram/app/components/flow/ItemCard.vue (1)

5-7: Typography tweak looks good

Bigger title improves hierarchy.

apps/atrium-telegram/app/pages/flow/[itemId]/index.vue (2)

8-10: Heading scale change is fine

Improves readability on detail view.


20-23: Meta name + canReturn: OK — active state uses route.name
definePageMeta name 'flow-itemId' and useRoute('flow-itemId') are present (apps/atrium-telegram/app/pages/flow/[itemId]/index.vue) and NavigationButton checks router.currentRoute.value.name via route.names.includes(...) (apps/atrium-telegram/app/components/NavigationButton.vue). No change required.

apps/web-app/server/tasks/ai/daily-report.ts (1)

56-61: Timezone/year formatting: reduce off-by-one and ambiguity.

The report date uses server time and omits the year. Near midnight or across year boundaries, titles can be misleading. Consider formatting with year and, if relevant, a fixed business timezone.

Example outside this hunk:

// Top: import { utcToZonedTime } from 'date-fns-tz'
const tz = process.env.TZ ?? 'Europe/Moscow'
const now = utcToZonedTime(new Date(), tz)
const date = format(now, 'd MMMM yyyy', { locale: ru })
apps/atrium-telegram/app/composables/useNavigation.ts (2)

9-23: LGTM on route-name arrays; aligns with meta-based navigation.


6-26: Verify page meta names exist for all included entries.

Ripgrep returned no hits under apps/atrium-telegram/app/pages; confirm each page referenced by useNavigation (apps/atrium-telegram/app/composables/useNavigation.ts:6-26) declares definePageMeta({ name: '...' }) for: index, flow-itemId, epic, epic-epicId, tasks.

apps/atrium-telegram/app/components/NavigationButton.vue (2)

9-10: Active styling via name-match looks good.

Also applies to: 31-32


18-21: Return icon condition depends on route.meta.canReturn — verification needed

File: apps/atrium-telegram/app/components/NavigationButton.vue (lines 18–21). Search for pages setting definePageMeta({ canReturn: true }) under apps/atrium-telegram/app/pages returned no matches; confirm inner pages set meta.canReturn where a return icon is expected or update the component to handle missing meta.

const router = useRouter()

const isThisRoute = computed(() => route.exact ? router.currentRoute.value.path === route.path : router.currentRoute.value.path.startsWith(route.path))
const isThisName = computed(() => route.names.includes(router.currentRoute.value.name))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Type-safety fix: route.name can be RouteRecordName | null.

Guard before includes to avoid TS errors and edge cases.

-const isThisName = computed(() => route.names.includes(router.currentRoute.value.name))
+const isThisName = computed(() => {
+  const n = router.currentRoute.value.name
+  return typeof n === 'string' && route.names.includes(n)
+})
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const isThisName = computed(() => route.names.includes(router.currentRoute.value.name))
const isThisName = computed(() => {
const n = router.currentRoute.value.name
return typeof n === 'string' && route.names.includes(n)
})
🤖 Prompt for AI Agents
In apps/atrium-telegram/app/components/NavigationButton.vue around line 47, the
computed uses route.names.includes(router.currentRoute.value.name) but
router.currentRoute.value.name can be RouteRecordName | null; guard against null
before calling includes by first reading router.currentRoute.value.name into a
local const, check it is not null (or is a string/RouteRecordName) and only then
call route.names.includes with the narrowed value so TypeScript is satisfied and
runtime edge cases are avoided.

@sonarqubecloud

Copy link
Copy Markdown

@hmbanan666 hmbanan666 merged commit 612b235 into main Sep 12, 2025
7 of 8 checks passed
@hmbanan666 hmbanan666 deleted the chore branch September 12, 2025 14:37

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (1)
apps/atrium-telegram/app/components/NavigationButton.vue (1)

56-56: Type-safety: guard currentRoute.name before includes

Same note as earlier review: router.currentRoute.value.name can be RouteRecordName | null. Narrow before includes.

-const isThisName = computed(() => route.names.includes(router.currentRoute.value.name))
+const isThisName = computed(() => {
+  const n = router.currentRoute.value.name
+  return typeof n === 'string' && route.names.includes(n)
+})
🧹 Nitpick comments (2)
apps/atrium-telegram/shared/types/index.ts (1)

17-22: Make route names immutable; keep badge optional but clarify zero-value behavior

  • Prefer a readonly array to avoid accidental mutation and reduce reactive churn.
  • Badge: upstream sets it from task count; make sure zero doesn’t render a chip (addressed in useNavigation/NavigationButton comments).
 export type NavigationRoute = {
   path: string
-  names: string[]
+  names: readonly string[]
   title: string
   icon: string
   exact?: boolean
   badge?: string
 }
apps/atrium-telegram/app/pages/tasks/index.vue (1)

41-45: Guard against undefined user id when passing current-user-id

There’s an explicit cast to string. If userStore.id isn’t populated yet, TaskList may receive an invalid id.

-      <TaskList
-        v-for="taskList in taskStore.myLists"
-        :key="taskList.id"
-        :list-id="taskList.id"
-        :current-user-id="userStore.id as string"
-      />
+      <template v-if="userStore.id">
+        <TaskList
+          v-for="taskList in taskStore.myLists"
+          :key="taskList.id"
+          :list-id="taskList.id"
+          :current-user-id="userStore.id"
+        />
+      </template>
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d5eb806 and d3f1fe0.

📒 Files selected for processing (5)
  • apps/atrium-telegram/app/components/NavigationButton.vue (3 hunks)
  • apps/atrium-telegram/app/composables/useNavigation.ts (1 hunks)
  • apps/atrium-telegram/app/pages/tasks/index.vue (3 hunks)
  • apps/atrium-telegram/app/stores/task.ts (3 hunks)
  • apps/atrium-telegram/shared/types/index.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
apps/atrium-telegram/app/stores/task.ts (2)
apps/atrium-telegram/app/stores/user.ts (1)
  • useUserStore (8-135)
packages/database/src/repository/task.ts (1)
  • lists (44-68)
apps/atrium-telegram/app/composables/useNavigation.ts (2)
apps/atrium-telegram/app/stores/task.ts (1)
  • useTaskStore (14-102)
apps/atrium-telegram/shared/types/index.ts (1)
  • NavigationRoute (15-22)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (7)
apps/atrium-telegram/app/stores/task.ts (2)

2-2: Good choice of @internationalized/date for TZ-safe “today” checks

LGTM.


95-97: Exposing computed APIs from the store

Exporting myLists/myTodayTasks from the store looks good and centralizes derivations.

apps/atrium-telegram/app/pages/tasks/index.vue (1)

15-26: Header copy/pluralization wired to store — looks good

Binding to taskStore.myTodayTasks.length and pluralization is correct.

apps/atrium-telegram/app/composables/useNavigation.ts (2)

6-7: Store usage inside shared composable

Using taskStore inside _useNavigation is fine and keeps badge reactive.


11-19: Verify route name arrays match actual record names

Ensure ['index','flow-itemId'] and ['epic','epic-epicId'] exactly match router.currentRoute.value.name values; otherwise isThisName will never activate.

Would you like a quick repo scan script to list discovered route names from pages/ to double-check?

apps/atrium-telegram/app/components/NavigationButton.vue (2)

9-10: Active styling by route or name

Broadening active state to include route name is correct.


18-21: Undo icon gating via meta.canReturn + name is reasonable

Assuming pages set meta.canReturn when appropriate.

Comment on lines +22 to +35
<UChip
v-else
:name="route.icon"
class="size-6 motion-preset-shake"
/>
size="3xl"
:show="!!route.badge"
:text="route.badge"
:ui="{
base: '-right-1 px-1.5 py-2 ring-2 tg-text-button font-bold motion-translate-y-loop-25 motion-duration-3500',
}"
>
<UIcon
:name="route.icon"
class="size-6 motion-preset-shake"
/>
</UChip>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Don’t show chip when badge is '0'

Guard with a numeric check to avoid rendering a “0” badge.

-      <UChip
-        v-else
-        size="3xl"
-        :show="!!route.badge"
-        :text="route.badge"
+      <UChip
+        v-else
+        size="3xl"
+        :show="Number(route.badge) > 0"
+        :text="route.badge"
         :ui="{
           base: '-right-1 px-1.5 py-2 ring-2 tg-text-button font-bold motion-translate-y-loop-25 motion-duration-3500',
         }"
       >
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<UChip
v-else
:name="route.icon"
class="size-6 motion-preset-shake"
/>
size="3xl"
:show="!!route.badge"
:text="route.badge"
:ui="{
base: '-right-1 px-1.5 py-2 ring-2 tg-text-button font-bold motion-translate-y-loop-25 motion-duration-3500',
}"
>
<UIcon
:name="route.icon"
class="size-6 motion-preset-shake"
/>
</UChip>
<UChip
v-else
size="3xl"
:show="Number(route.badge) > 0"
:text="route.badge"
:ui="{
base: '-right-1 px-1.5 py-2 ring-2 tg-text-button font-bold motion-translate-y-loop-25 motion-duration-3500',
}"
>
<UIcon
:name="route.icon"
class="size-6 motion-preset-shake"
/>
</UChip>
🤖 Prompt for AI Agents
In apps/atrium-telegram/app/components/NavigationButton.vue around lines 22–35,
the UChip currently uses :show="!!route.badge" which causes a "0" badge to
render; change the show binding to a numeric check like
:show="Number(route.badge) > 0" (or use parseInt and isFinite if you expect
non-numeric values) so the chip only renders when the badge value is a positive
number.

Comment on lines 23 to 28
path: '/tasks',
name: 'tasks',
names: ['tasks'],
title: t('app.my-tasks'),
icon: 'i-lucide-layout-dashboard',
badge: taskStore.myTodayTasks.length.toString(),
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Avoid showing a “0” badge for /tasks

Currently badge is always a string; '0' is truthy and will render a chip. Return undefined when count is zero.

     {
       path: '/tasks',
       names: ['tasks'],
       title: t('app.my-tasks'),
       icon: 'i-lucide-layout-dashboard',
-      badge: taskStore.myTodayTasks.length.toString(),
+      badge: taskStore.myTodayTasks.length > 0
+        ? String(taskStore.myTodayTasks.length)
+        : undefined,
     },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
path: '/tasks',
name: 'tasks',
names: ['tasks'],
title: t('app.my-tasks'),
icon: 'i-lucide-layout-dashboard',
badge: taskStore.myTodayTasks.length.toString(),
},
path: '/tasks',
names: ['tasks'],
title: t('app.my-tasks'),
icon: 'i-lucide-layout-dashboard',
badge: taskStore.myTodayTasks.length > 0
? String(taskStore.myTodayTasks.length)
: undefined,
},
🤖 Prompt for AI Agents
In apps/atrium-telegram/app/composables/useNavigation.ts around lines 23 to 28,
the badge is always set to a string which renders a "0" chip; change the badge
to return undefined when the task count is zero. Replace the current badge
expression with a conditional that checks taskStore.myTodayTasks.length === 0
and returns undefined in that case, otherwise returns the numeric count as a
string (or number) so no "0" badge is shown.

Comment on lines +19 to +27
const userStore = useUserStore()

const myLists = computed(() =>
lists.value.filter(
(taskList) => taskList.chat?.members.some((member) => member.userId === userStore.id),
).filter((taskList) => isTodayOnly.value ? taskList.tasks.filter((task) => !task.completedAt && task.date && isToday(parseDate(task.date), getLocalTimeZone())).length : true),
)
const myTodayTasks = computed(() => myLists.value.flatMap((taskList) => taskList.tasks.filter((task) => !task.completedAt && task.date && isToday(parseDate(task.date), getLocalTimeZone()))))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Predicate returns number; fix boolean logic and avoid repeated TZ lookups

The second filter relies on a numeric length for truthiness, which is a TS type mismatch. Also, you call getLocalTimeZone repeatedly inside tight loops.

   const userStore = useUserStore()
 
-  const myLists = computed(() =>
-    lists.value.filter(
-      (taskList) => taskList.chat?.members.some((member) => member.userId === userStore.id),
-    ).filter((taskList) => isTodayOnly.value ? taskList.tasks.filter((task) => !task.completedAt && task.date && isToday(parseDate(task.date), getLocalTimeZone())).length : true),
-  )
-  const myTodayTasks = computed(() => myLists.value.flatMap((taskList) => taskList.tasks.filter((task) => !task.completedAt && task.date && isToday(parseDate(task.date), getLocalTimeZone()))))
+  const tz = getLocalTimeZone()
+  const isTaskForToday = (task: Task) =>
+    !task.completedAt && task.date && isToday(parseDate(task.date), tz)
+
+  const myLists = computed(() =>
+    lists.value
+      .filter((taskList) =>
+        taskList.chat?.members.some((member) => member.userId === userStore.id),
+      )
+      .filter((taskList) => !isTodayOnly.value || taskList.tasks.some(isTaskForToday)),
+  )
+  const myTodayTasks = computed(() =>
+    myLists.value.flatMap((taskList) => taskList.tasks.filter(isTaskForToday)),
+  )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const userStore = useUserStore()
const myLists = computed(() =>
lists.value.filter(
(taskList) => taskList.chat?.members.some((member) => member.userId === userStore.id),
).filter((taskList) => isTodayOnly.value ? taskList.tasks.filter((task) => !task.completedAt && task.date && isToday(parseDate(task.date), getLocalTimeZone())).length : true),
)
const myTodayTasks = computed(() => myLists.value.flatMap((taskList) => taskList.tasks.filter((task) => !task.completedAt && task.date && isToday(parseDate(task.date), getLocalTimeZone()))))
const userStore = useUserStore()
const tz = getLocalTimeZone()
const isTaskForToday = (task: Task) =>
!task.completedAt && task.date && isToday(parseDate(task.date), tz)
const myLists = computed(() =>
lists.value
.filter((taskList) =>
taskList.chat?.members.some((member) => member.userId === userStore.id),
)
.filter((taskList) => !isTodayOnly.value || taskList.tasks.some(isTaskForToday)),
)
const myTodayTasks = computed(() =>
myLists.value.flatMap((taskList) => taskList.tasks.filter(isTaskForToday)),
)
🤖 Prompt for AI Agents
In apps/atrium-telegram/app/stores/task.ts around lines 19 to 27, the second
.filter uses a numeric .length as a boolean (causing a TS type mismatch) and
calls getLocalTimeZone() repeatedly inside loops; change the predicate to
explicitly return a boolean (e.g., use .some(...) or .filter(...).length > 0)
and compute getLocalTimeZone() once outside the computed to reuse the value, and
also avoid redundant parseDate calls by evaluating task date/isToday once per
task (e.g., create a small helper or reuse a local variable inside the
callbacks) so the filters return proper booleans and eliminate repeated TZ
lookups.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant